const { Group } = require('board-game');
const extend = require('extend');

const {game: gameConfig} = require('./config');

const directions = {
    'up': [ gameConfig.directions.right, gameConfig.directions.left ],
    'down': [ gameConfig.directions.right, gameConfig.directions.left ],
    'right': [ gameConfig.directions.up, gameConfig.directions.down ],
    'left': [ gameConfig.directions.up, gameConfig.directions.down ],
}

class MazeGroup extends Group {
    constructor(server, game, index, option, roles) {
        super(server, game, index, option, roles);
        this.shown = false;
        this.needCheck = 0;
        this.checkDirection = false;
    }

    initShown(size) {
        this.shown = new Array(size).fill(0x01FF).map(_ => new Array(size).fill(0x01FF));
        this.needCheck = 0;
        this.checkDirection = false;
    }

    openShown(x, y) {
        const size = this.shown.length;
        if ((this.shown[y][x] & 0x0010) === 0x0010) {
            let w = 0;
            for (let dx = x - 1; dx <= x + 1; dx++) {
                if (dx < 0) {
                    w += 3;
                } else if (dx < size) {
                    for (let dy = y - 1; dy <= y + 1; dy++) {
                        if (dy < 0 || dy >= size) {
                            w++;
                        } else {
                            this.shown[dy][dx] &= (~(1 << (w++))) & 0x01FF;
                        }
                    }
                }
            }
        }
    }

    checkShown(board, directionName, role) {
        directionName = directionName || this.checkDirection;
        const direction = gameConfig.directions[directionName];
        const sides = directions[directionName];
        const size = board.map.length;
        for (let i = 1; i < 5; i++) {
            let x = role.location.x + direction.x * i;
            let y = role.location.y + direction.y * i;
            if (x < 0 || y < 0 || x >= size || y >= size) break;
            if (i > Math.max(1, this.needCheck) && (this.shown[y][x] & 0x0010) === 0x0010) {
                this.needCheck = i + 1;
                this.checkDirection = directionName;
                break;
            }
            this.openShown(x, y);
            for (const side of sides) {
                let sx = x + side.x;
                let sy = y + side.y;
                if (sx < 0 || sy < 0 || sx >= size || sy >= size) continue;
                this.openShown(sx, sy);
            }
            if (board.map[y][x] === 1) {
                this.needCheck = 0;
                this.checkDirection = false;
                break;
            }
            if (i === 4) {
                this.needCheck = 0;
                this.checkDirection = false;
            }
        }
        this.refreshShown();
    }

    clearShown() {
        this.shown = false;
        for (const role of this.roles) {
            role.shown = false;
        }
    }

    refreshShown() {
        for (const role of this.roles) {
            role.shown = this.shown;
        }
    }
}

module.exports = MazeGroup;